using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text.RegularExpressions;

using Danser_AJAXEnabledWebApplication.DataSourceManagers;
using Danser_AJAXEnabledWebApplication.Faults;
using Danser_AJAXEnabledWebApplication.PageExt.Utilities;
using Danser_Control.Managers;
using Danser_Control.Exceptions;
using Danser_Entity.Entities;

namespace Danser_AJAXEnabledWebApplication
{
    /// <summary>
    /// Abstract Danser page which all main pages inherit from
    /// </summary>
    public abstract partial class AbstractPage : System.Web.UI.Page
    {
        #region Members:

        /// <summary>
        /// reference to master page
        /// </summary>
        private Danser master;
        
        /// <summary>
        /// control manager to get User services 
        /// </summary>
        private IUserManager userManager;

        /// <summary>
        /// handle formatting UI elements
        /// </summary>
        protected PageFormatter _pageFormatter;

        #endregion

        #region page Load:

        /// <summary>
        /// The inherit pages must call this method (by base), and then 
        /// continue with their own loading
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void Page_Load(object sender, EventArgs e)
        {
            _pageFormatter = new PageFormatter();

            master = this.Master as Danser;
            if (master == null)
            {
                //throw some exception!! or error page
            }

            userManager = ManagerFactory.UserManager();

            String userID = GetRequestingUserID();
            master.UserPermission = ValidatePermission(userID);

            master.UserID = userID;

            master.exposeRelevantButtons(master.UserPermission);
        }

        #endregion

        #region Helpers:

        /// <summary>
        /// Validate permission of user requesting to view this concrete page
        /// </summary>
        private PermissionLevel ValidatePermission(String userID)
        {
            PermissionLevel permission = PermissionLevel.Viewer; //default
            try
            {
                if (userManager.IsUserExists(userID))
                    permission = userManager.GetUserPermission(userID);

                bool permitted = InnerValidatePermission(permission);

                if (!permitted)
                {
                    throw new DanserAuthorizationException(ErrorMessages.PermissionDenied);

                }

            }
            catch (DanserAuthorizationException e)
            {
                //redirect to authorization error page
                HandleAuthorizationErrorPage(e);
            }

            return permission;
        }

        /// <summary>
        /// Return the user id extracte from the request 
        /// </summary>
        /// <returns></returns>
        private String GetRequestingUserID()
        {
            String machineAndUser = Request.LogonUserIdentity.Name;
            String[] accountDetails =
                machineAndUser.Split(
                    new String[] { "\\" },
                    StringSplitOptions.RemoveEmptyEntries);

            String domain = accountDetails[0];
            String userID = accountDetails[1];

            return userID;
        }

        #endregion

        #region Abstract InnerValidatePermission Method:

        /// <summary>
        /// Implemented by each inheriting page according to its unique permission level
        /// </summary>
        /// <param name="permissionlevel">Permission level to check if valid</param>
        /// <returns>true if permission is as expected, false if not</returns>
        protected abstract bool InnerValidatePermission(PermissionLevel permissionlevel);

        #endregion

        #region ErrorPageHandlers:

        /// <summary>
        /// redirect to general error page
        /// </summary>
        /// <param name="exception"></param>
        public void HandleGenericErrorPage(Exception exception)
        {
            Session[GenericErrorPage.SESSION_ERROR_KEY] = exception;
            Response.Redirect(GenericErrorPage.SESSION_ERROR_PAGE_URL_KEY);
        }

        /// <summary>
        /// redirect to authorization error page
        /// </summary>
        /// <param name="exception"></param>
        public void HandleAuthorizationErrorPage(DanserAuthorizationException exception)
        {
            Session[UnAuthorizedAccess.SESSION_ERROR_KEY] = exception;
            Response.Redirect(UnAuthorizedAccess.SESSION_ERROR_URL_KEY);
        }

        #endregion
    }
}
